Micron Document




Python syntax and semantics
part 26/45 · 74.8 KB total
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
and you can see that b, as visible from the closure's scope, retains the value it had; the changed binding of b inside the inner function did not propagate out. The way around this is to use a nonlocal b statement in bar. In Python 2 (which lacks nonlocal), the usual workaround is to use a mutable value and change that value, not the binding. E.g., a list with one element.

Generators

Introduced in Python 2.2 as an optional feature and finalized in version 2.3, generators are Python's mechanism for lazy evaluation of a function that would otherwise return a space-prohibitive or computationally intensive list.

This is an example to lazily generate the prime numbers:

from itertools import count
def generate_primes(stop_at=None):
primes = []
for n in count(start=2):
if stop_at is not None and n > stop_at:
return # raises the StopIteration exception
composite = False
for p in primes:
if not n % p:
composite = True
break
elif p ** 2 > n:
break
if not composite:
primes.append(n)
yield n

When calling this function, the returned value can be iterated over much like a list:

for i in generate_primes(100): # iterate over the primes between 0 and 100
print(i)
for i in generate_primes(): # iterate over ALL primes indefinitely
print(i)

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────